home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
program
/
cgazv3n4.zip
/
DOS4-DIR.ZIP
/
DOS4.C
< prev
next >
Wrap
Text File
|
1989-04-11
|
12KB
|
333 lines
/**************************** DOS4.C **********************************\
|* *|
|* DOS4.C - demonstrate usage of extended DOS 4.0 disk functions *|
|* *|
|* (c) Copyright 1989, David Craig. All rights reserved. *|
|* Permission is granted to incorporate these functions into a larger *|
|* work and to distribute the resulting executable file. *|
|* *|
|* Usage: dos4 drive *|
|* *|
|* Returns: detailed disk summary for given drive *|
|* *|
|* Compilers: TurboC 2.0, MSC 5.1 *|
|* Memory models: any *|
\**********************************************************************/
/* must prevent MSC from word aligning contents of our structures */
#pragma pack (1)
#include "local.h"
#include "dos4.h"
#if !defined(MK_FP)
#define MK_FP(seg,ofs) ((void far *) (((unsigned long)(seg)<<16) \
| (unsigned)(ofs)))
#endif
#define TRUE 1
#define ENTRY_LENGTH 32
int save_current_drive;
struct disk_table tbl;
struct packet pkt;
dword not_used_sectors;
word abs_read_error;
int abs_read(int drive, word nsectors, word sector, void *buffer);
word getdfs(int drive, word *avail, word *total, word *sectsize);
int current_drv(void);
struct disk_table far *get_table(int drv);
void print_vol(int drive, struct disk_table *tbl);
void print_disk_tbl(int drive, struct disk_table *tbl);
void print_bios_parameter_block(int drive, struct boot *bpb);
void check_compatibility(int drive, struct boot *bpb,
struct disk_table *tbl);
void print_master_boot_record(int drive);
void print_error_message(void);
int main(int argc, char **argv)
{
int drive;
int ver;
struct disk_table far *tbl_ptr;
struct boot *bpb;
printf("%s (c) 1989 David J. Craig, All rights reserved.\n",
argv[0]);
if(signal(SIGINT, SIG_IGN) == SIG_ERR)
{
cputs("\r\nCouldn't set SIGINT.\r\n");
abort();
}
ver = _osmajor * 100 + _osminor;
if(ver < 400 || ver > 409)
{
printf("\aIncorrect DOS version %d.%02d.\n\a", _osmajor, _osminor);
abort();
}
if(argc > 1)
{
drive = tolower(*argv[1]) - 'a';
}
else
{
printf("\nDrive must be specified.\n\a");
abort();
}
bpb = (struct boot *) malloc(2048);
if(bpb == NULL)
{
fprintf(stderr, "\n\aInsufficient memory available.\n\a");
abort();
}
if(abs_read(drive, 1, 0, bpb))
{
fprintf(stderr, "\n\aUnable to read drive via INT 25h.\n\a");
print_error_message();
abort();
}
tbl_ptr = get_table(drive);
tbl = *tbl_ptr;
print_disk_tbl(drive, &tbl);
print_bios_parameter_block(drive, bpb);
free(bpb);
return(0);
}
void print_error_message()
{
word upper;
word lower;
upper = (abs_read_error & 0xff00) >> 8;
lower = abs_read_error & 0x00ff;
switch(upper)
{
case 0x80:
fprintf(stderr, "Attachment failed to respond.\n");
break;
case 0x40:
fprintf(stderr, "SEEK operation failed.\n");
break;
case 0x08:
fprintf(stderr, "Bad CRC on diskette read.\n");
break;
case 0x04:
fprintf(stderr, "Requested sector not found.\n");
break;
case 0x03:
fprintf(stderr, "Write attempt on write-protected diskette.\n");
break;
case 0x02:
fprintf(stderr, "Error other than types listed above.\n");
break;
default:
fprintf(stderr, "Unknown error - AH = 0x%02X.\n", upper);
break;
}
switch(lower)
{
case 0x00:
fprintf(stderr, "Attempt to write on write-protected diskette.\n");
break;
case 0x01:
fprintf(stderr, "Unknown unit.\n");
break;
case 0x02:
fprintf(stderr, "Drive not ready.\n");
break;
case 0x03:
fprintf(stderr, "Unknown command.\n");
break;
case 0x04:
fprintf(stderr, "Data error (CRC).\n");
break;
case 0x05:
fprintf(stderr, "Bad request structure length.\n");
break;
case 0x06:
fprintf(stderr, "Seek error.\n");
break;
case 0x07:
fprintf(stderr, "Unknown media type.\n");
break;
case 0x08:
fprintf(stderr, "Sector not found.\n");
break;
case 0x09:
fprintf(stderr, "Printer out of paper.\n");
break;
case 0x0a:
fprintf(stderr, "Write fault.\n");
break;
case 0x0b:
fprintf(stderr, "Read fault.\n");
break;
case 0x0c:
fprintf(stderr, "General failure.\n");
break;
default:
fprintf(stderr, "Unknown error - AL = 0x%02X.\n", lower);
break;
}
return;
}
void print_disk_tbl(int drive, struct disk_table *tbl)
{
printf("\nDOS function 32h Disk's Table for Drive = %c:.\n\n",
drive + 'A');
printf("Assigned Disk = %u.\n",
tbl->designator);
printf("Unit Number = %u.\n",
tbl->unit_number);
printf("Bytes per Sector = %u.\n",
tbl->sector_size);
printf("Sectors per cluster - 1 = %u.\n",
tbl->cluster_size);
printf("Shift Count for Sector/Cluster Conversion = %u.\n",
tbl->shift_value);
printf("Fat Start (Reserved Sectors) = %u.\n",
tbl->fat_start);
printf("Number of copies of the FAT = %u.\n",
tbl->fat_copies);
printf("Maximum Directory Entries = %u.\n",
tbl->max_entries);
printf("First Usable Sector (Data Begins) = %u.\n",
tbl->first_sector);
printf("Total Cluster Count = %u.\n",
tbl->last_cluster);
printf("Sectors in FAT = %u.\n",
tbl->fat_size);
printf("First Directory Sector = %u.\n",
tbl->dir_start);
printf("Media Descriptor = %X.\n",
tbl->media_type);
printf("Device Driver Address = %Fp.\n",
tbl->ddh);
printf("Drive Used Flag = %X.\n",
tbl->drive_used);
printf("Chain to Next Disk Table = %Fp.\n",
tbl->nxt);
if(FP_OFF(tbl->nxt) != 0xffff)
printf("Assigned Disk (Next Disk Table) = %c:.\n",
tbl->nxt->designator + 'A');
else
printf("Last Disk Table in Chain.\n");
printf("\n");
return;
}
void print_bios_parameter_block(int drive, struct boot *bpb)
{
int i;
printf("\nBIOS Parameter Block for Drive = %c:.\n\n",
drive + 'A');
printf("First 3 bytes (jump) = %X%X%X.\n",
bpb->jump[0], bpb->jump[1], bpb->jump[2]);
printf("OEM Name = ");
for(i = 0; i < 8; i++)
putchar(bpb->oem_name[i]);
printf(".\n");
printf("Bytes per sector = 0x%04X - %u.\n",
bpb->bytes_per_sector, bpb->bytes_per_sector);
printf("Sectors per allocation unit = 0x%02X.\n",
bpb->sectors_per_au);
printf("Reserved sectors (FAT start) = 0x%04X.\n",
bpb->reserved_sectors);
printf("Number of FATs = 0x%02X.\n",
bpb->number_of_fats);
printf("Maximum number of root directory entries = 0x%04X - %u.\n",
bpb->number_of_entries, bpb->number_of_entries);
if(bpb->number_of_sectors)
{
printf("Number of sectors = 0x%04X - %u.\n",
bpb->number_of_sectors, bpb->number_of_sectors);
}
else
{
printf("Number of sectors = Zero.\n");
}
printf("Media descriptor = %02X.\n",
bpb->media_descriptor);
printf("FAT size = %u.\n",
bpb->fat_size);
printf("Sectors per track = %u.\n",
bpb->sectors_per_track);
printf("Number of heads = %u.\n",
bpb->number_of_heads);
printf("Number of hidden sectors = 0x%lX - %lu.\n",
bpb->hidden_sectors, bpb->hidden_sectors);
printf("Big number of sectors = 0x%lX - %lu.\n",
bpb->big_number_of_sectors, bpb->big_number_of_sectors);
printf("Physical drive number = 0x%02X.\n",
bpb->physical_drive_number);
printf("Reserved = 0x%02X.\n",
bpb->bpb_reserved);
printf("Extended boot record signature = 0x%02X.\n",
bpb->extended_boot_record_sig);
if(bpb->extended_boot_record_sig == 0x29)
{
printf("Volume serial number = %04X-%04X.\n",
FP_SEG(bpb->volume_serial_number),
FP_OFF(bpb->volume_serial_number));
printf("Volume Label = ");
for(i = 0; i < 11; i++)
putchar(bpb->volume_label[i]);
printf(".\n");
printf("BIOS Parameter Block FAT Size = ");
for(i = 0; i < 8; i++)
putchar(bpb->bpb_fat_id[i]);
printf(".\n");
}
printf("\n");
return;
}
int abs_read(int drive, word nsectors, word sector, void *buffer)
{
union REGS regs;
struct SREGS sregs;
struct packet far *packt;
/* first try a standard read */
regs.h.al = ( byte ) drive;
regs.x.cx = nsectors;
regs.x.dx = sector;
segread(&sregs);
regs.x.bx = (word) buffer;
(void) int86x(0x25, ®s, ®s, &sregs);
/* DOS 4.x will tell us if we are reading a 32meg+ partition... */
if(regs.x.cflag && regs.x.ax == 0x0207)
{
packt = (struct packet far *) &pkt; /* must set up packet */
regs.h.al = ( byte ) drive;
pkt.starting_sector = (dword) sector;
pkt.nbr_sectors = nsectors;
pkt.buffer = buffer;
sregs.ds = FP_SEG(packt);
regs.x.bx = FP_OFF(packt);
regs.x.cx = 0xffff;
(void) int86x(0x25, ®s, ®s, &sregs); /* read again */
}
abs_read_error = regs.x.ax;
return( (int) regs.x.cflag);
}
struct disk_table far *get_table(int drv)
{
struct disk_table far *t;
union REGS regs;
struct SREGS segregs;
regs.x.ax = 0x3200;
regs.x.dx = drv + 1;
segread(&segregs);
intdosx(®s, ®s, &segregs);
t = MK_FP(segregs.ds, regs.x.bx);
return(t);
}